//
//  VPlayArea.cpp
//  app-ios gl
//
//  Created by MeherTj on 2022/1/21.
//  Copyright © 2022 lover. All rights reserved.
//

#include "VPlayArea.hpp"
#include "Gesture.hpp"
#include "Ctrl.hpp"

void VPlayArea::loadView()
{
	auto vs = VConfigs::Get()->getViewSize();
	Vec2 move = { vs.w / 2.f, 840.f };
	m_blocks_position = move;
	auto pan = std::make_shared<VPlayAreaPan>();
	this->addNode(pan);
	pan->setPosition(move);//, <#float y#>)
	m_pan = pan.get();

	auto score_bar = std::make_shared<VPlayScoreBar>();
	this->addNode(score_bar);
	m_score_bar = score_bar.get();

	auto blocks = std::make_shared<VPlayBlocks>();
	this->addNode(blocks);
	blocks->setPosition(move);
	m_play_blocks = blocks.get();

	auto t = std::make_shared<VTetrisBlocks>();
	this->addNode(t);
	float s = 0.3f;
	t->setScale( {s, s});
	t->setPosition({vs.w / 2.f, vs.h - 140.f});
	m_next_tetris = t.get();

	auto current = std::make_shared<VTetrisBlocks>();
	this->addNode(current);
	m_current_tetris = current.get();

	this->runAction(ActionCall::Create([this](float delay, int)->bool {
		this->onUpdate(delay);
		return true;
	}, 0, 1.f/30.f));

	auto ges = std::make_shared<Gesture>();
	ges->setPriority(1);
	Activity::Get()->getTouchDispatcher()->bindTouchHandle(ges);
	m_gesture = ges.get();
//	Result result;
//	result.cleared_lines = { 1, 2, 3};
//	blocks->clearLines(result, []() {
//
//	});
}
void VPlayArea::setCtrlUpdate(std::function<void (float)> onTick)
{
	m_ctrl_update = onTick;

}
//void VPlayArea::updateMap(const Map &map) {
//	m_play_blocks->resetBlocks(map, nullptr);
//}

void VPlayArea::onUpdate(float interval)
{
	if(m_ctrl_update) m_ctrl_update(interval);

	if(m_gesture) {
		m_gesture->onUpdate(interval);
	}
}

void VPlayArea::setGestureEvent(std::function<void (GestureType)> onEvent) {
	m_gesture->onEvent = onEvent;
}

void VPlayBlocks::resetBlocks(const Map &map) {
	for(int i = 0; i < GMapHeight; ++i)
	{
		for(int j = 0; j < GMapWidth; ++j)
		{
			m_blocks[i][j]->setBlockColorCode(map.get_value_at(j, i));
		}
	}
}

void VPlayArea::updateNextTetris(TetrisInfo info)
{
	m_next_tetris->setStatus(info, 1);
}

void VPlayArea::updateCurrentTetris(TetrisInfo info, Pos pos) {
	m_current_tetris->setVisible(true);

	m_current_tetris->setStatus(info);
	m_current_tetris->setPosition(m_blocks_position + m_play_blocks->getSubPosition(pos.x, pos.y));
//	LogD("current:%f %f", p.x, p.y);
}
Vec2 VPlayBlocks::getSubPosition(int x, int y)
{
	return m_block_view_lb + Vec2{m_block_view_width*x, m_block_view_width*y};
}
void VPlayBlocks::loadView()
{
	float len = 80.f;
	float x0 = len * (-GMapWidth/2 + 0.5f);
	float y = len * (-GMapHeight/2 + 0.5f);

	m_block_view_lb = { x0, y };

	for(int i = 0; i < GMapHeight; ++i)
	{
		float x = x0;
		for(int j = 0; j < GMapWidth; ++j) {
			auto block = std::make_shared<VBlock>();
			block->setOrder(2);
			this->addNode(block);
			block->setPosition({x, y});
			m_blocks[i][j] = block.get();
			x+=len;

			// debug
			block->setBlockColorCode(g_random.next(GBlockColorCount) + 1);
		}
		y += len;
	}
	m_block_view_width = len;
}

void VPlayAreaPan::loadView()
{
	auto bg = std::make_shared<Sprite>();
	bg->setTexture(TexturesCache::Get()->getTexture(GetPath("pan")));
	this->addNode(bg);
	m_pan_bg = bg.get();

	bg->setAnchor({0.5f, 0.5f});
	bg->setPosition({0, 0});
}

void VPlayScoreBar::loadView()
{
	auto bg = std::make_shared<Sprite>();
	bg->setTexture(GetTexture(GetPath("bar")));
	this->addNode(bg);

	auto vs = VConfigs::Get()->getViewSize();
	auto es = VConfigs::Get()->getEdgeSize();
	bg->setAnchor({0.5f, 1.f});
	bg->setPosition({vs.w/2, vs.h});

//	bg->setAnchor({0.f, 0.f});
//	bg->setPosition({100, vs.h - 300});
//	bg->runAction(ActionCall::Create([bg](float, int) {
//		bg->setRotation(bg->getRotation() + 0.5f);
//		return true;
//	}, 0));

#if 0
	auto lb = std::make_shared<FontLabel>();
	lb->setAnchor({0.5f, 0.5f});
	lb->setPosition({ 140.f+es.w, vs.h - 142.f + es.h });
	lb->setFontBrush(VConfigs::Get()->font_brush_normal);
	lb->setFontSize(64);
	this->addNode(lb);
	m_score_lb = lb.get();
	lb->setText("0");
#endif

	auto tile_font = std::make_shared<TilemapFont>();
	tile_font->load(TexturesCache::Get()->getTexture(GetPath("num")), {0, 0, 1, 1}, ' ', 40, 1);
	auto lb_tile = std::make_shared<TilemapLabel>();
	lb_tile->setTileMap(tile_font);
	lb_tile->setCharSpacing(0.f);
	lb_tile->setScale(Vec2Make(40.f/64.f));

	lb_tile->setAnchor({0.5f, 0.5f});
	lb_tile->setPosition({ 140.f+es.w, vs.h - 142.f + es.h });
	//	lb_tile->setAnchor({0.5f, 0.5});
	this->addNode(lb_tile);
	m_score_lb = lb_tile.get();
	m_score_lb->setText("0232");
	m_score_lb->setFlipY(1);


//	lb_tile->runAction(ActionCall::Create([this](float, int) {
//		m_tile->setRotation(m_tile->getRotation() + 0.5f);
//		return true;
//	}, 0));
}

void VPlayScoreBar::setScore(int score) {
	if(score == m_score_value) return;
	m_score_lb->setText(std::to_string(score));
	m_score_value = score;
}

void VPlayBlocks::clearLines(const Result &result, std::function<void ()> onDone)
{
	static const int RepN = 4;
	auto blink = ActionCall::Create([this,result](float, int n)->bool {
		bool v = n%2;
		for(auto i : result.cleared_lines) {
			for(int x = 0; x < GMapWidth; ++x)
			{
				m_blocks[i][x]->setVisible(v);
			}
		}
		return true;
	}, RepN, 0.f, 0.05f);
	auto call = ActionCall::Create([onDone](float, int) ->bool {
		if(onDone) onDone();
		return false;
	}, 1);
	this->runAction(ActionSequence::Create({blink, call}));
}
//Node * VPlayArea::on

void VPlayArea::updateMap(Map const & map)
{
	m_play_blocks->resetBlocks(map);
}

void VPlayArea::updateScore(int score) {
	m_score_bar->setScore(score);
}

void VPlayArea::checkResult(Result const & result, std::function<void()> onDone) {

	m_current_tetris->setVisible(false);
	m_play_blocks->clearLines(result, onDone);
}

void VPlayArea::runFaild(std::function<void()> onDone) {
	this->runAction(ActionCall::Create([onDone](float, int){
		onDone();
		return false;
	}, 1));
}

void VPlayArea::restartGame(std::function<void()> onDone) {

}
